﻿using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;

namespace Songhay.Silverlight.BiggestBox.AdditionalSamplesPart.ViewModels
{
    using Songhay.Mvvm.Models;
    using Songhay.Mvvm.ViewModels;
    using Songhay.Mvvm.Views;

    /// <summary>
    /// ContentPresenter with UserControl Collection View Model
    /// </summary>
    public class TransitioningContentControlSampleViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TransitioningContentControlSampleViewModel"/> class.
        /// </summary>
        /// <remarks>
        /// For details, see
        /// “How to: Implement Property Change Notification”
        /// http://msdn.microsoft.com/en-us/library/ms743695.aspx
        /// A sample <c>set</c> block:
        /// <code>
        /// set
        /// {
        /// _myProperty = value;
        /// OnPropertyChanged("MyProperty");
        /// }
        /// </code>
        /// </remarks>
        public TransitioningContentControlSampleViewModel()
        {
            if(this.IsInDesignMode) this.SetDesignTime();

            this._canExecuteItemInCollectionCommand = true;

            #region commanding:

            this.NextItemInCollectionCommand = new RelayCommand(
            () =>
            {
                if(!this._canExecuteItemInCollectionCommand) return;
                if(!this.HasValidControlsCollection()) return;

                this._canExecuteItemInCollectionCommand = false;
                this._currentlySelectedControlIndex++;
                this.CurrentlySelectedControlIndex =
                    (this._currentlySelectedControlIndex >= this.Controls.Count) ?
                        0 : this._currentlySelectedControlIndex;
            });

            this.PreviousItemInCollectionCommand = new RelayCommand(
            () =>
            {
                if(!this._canExecuteItemInCollectionCommand) return;
                if(!this.HasValidControlsCollection()) return;

                this._canExecuteItemInCollectionCommand = false;
                this._currentlySelectedControlIndex--;
                this.CurrentlySelectedControlIndex =
                    (this._currentlySelectedControlIndex < 0) ?
                        (this.Controls.Count - 1) : this._currentlySelectedControlIndex;
            });

            this.TransitionCompletedCommand = new RelayCommand(
            () =>
            {
                this._canExecuteItemInCollectionCommand = true;
            });

            #endregion

            #region eventing:

            this.PropertyChanged += (s, args) =>
            {
                switch(args.PropertyName)
                {
                    case "CurrentlySelectedControlIndex":
                        this.CurrentlySelectedControl = this.Controls[this.CurrentlySelectedControlIndex];
                        break;
                }
            };

            #endregion

            #region messaging:

            Messenger.Default.Register<LightMessage<ObservableCollection<UserControl>>>(this,
            message =>
            {
                if(message.Source != LightMessageSource.View) return;
                if(message.UniqueId != "TransitioningContentControlSample") return;

                this.Controls = message.Content;
                if(!this.HasValidControlsCollection()) return;
                this.CurrentlySelectedControl = this.Controls[0];
                this.CurrentlySelectedControlIndex = 0;
            });

            #endregion
        }

        /// <summary>
        /// Gets or sets the controls.
        /// </summary>
        /// <value>The controls.</value>
        public ObservableCollection<UserControl> Controls
        {
            get { return this._controls; }
            set
            {
                this._controls = value;
                base.RaisePropertyChanged("Controls");
            }
        }

        /// <summary>
        /// Gets or sets the currently selected control.
        /// </summary>
        /// <value>The currently selected control.</value>
        public UserControl CurrentlySelectedControl
        {
            get { return this._currentlySelectedControl; }
            set
            {
                this._currentlySelectedControl = value;
                base.RaisePropertyChanged("CurrentlySelectedControl");
            }
        }

        /// <summary>
        /// Gets or sets the index of the currently selected control.
        /// </summary>
        /// <value>The index of the currently selected control.</value>
        public int CurrentlySelectedControlIndex
        {
            get { return this._currentlySelectedControlIndex; }
            set
            {
                this._currentlySelectedControlIndex = value;
                base.RaisePropertyChanged("CurrentlySelectedControlIndex");
            }
        }

        /// <summary>
        /// Gets or sets the next item in collection command.
        /// </summary>
        /// <value>The next item in collection command.</value>
        public ICommand NextItemInCollectionCommand { get; private set; }

        /// <summary>
        /// Gets or sets the previous item in collection command.
        /// </summary>
        /// <value>The previous item in collection command.</value>
        public ICommand PreviousItemInCollectionCommand { get; private set; }

        /// <summary>
        /// Gets or sets the transition completed command.
        /// </summary>
        /// <value>The transition completed command.</value>
        public ICommand TransitionCompletedCommand { get; private set; }

        bool HasValidControlsCollection()
        {
            return (this.Controls != null) &&
                (this.Controls.Count >= 3);
        }

        void SetDesignTime()
        {
            this.CurrentlySelectedControl = new DesignTimePlaceholder
            {
                BorderBrush = new SolidColorBrush(Color.FromArgb(255, 128, 0, 0)),
                Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 0, 0)),
                Height = 320,
                Width = 320
            };
        }

        ObservableCollection<UserControl> _controls;
        UserControl _currentlySelectedControl;
        int _currentlySelectedControlIndex;
        bool _canExecuteItemInCollectionCommand;
    }
}
